import React, { useState, useMemo, useEffect, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { connect } from 'react-redux';

import { NavBar, SearchBar, IndexBar, List } from 'antd-mobile';
import { CloseOutline } from 'antd-mobile-icons';

import { changeCity, getCityList } from '../redux/action/CityActionCreator';
import { clearCinemaList } from '../redux/action/CinemaActionCreator';
import { useAutoHandleTabbar } from '../hooks/useTabbar';

import style from '../css/city.module.css';

/**
 * 按照拼音首字母排序
 * @param {*} cityList
 * @returns
 */
const citySort = (cityList = []) => {
  return cityList.toSorted((a, b) => {
    return (
      a.pinyin.substr(0, 1).toUpperCase().charCodeAt() -
      b.pinyin.substr(0, 1).toUpperCase().charCodeAt()
    );
  });
};

/**
 * 根据名称或者拼音过滤
 * @param {*} cityList
 * @param {*} name
 * @returns
 */
const citySearch = (cityList = [], name = '') => {
  return cityList.filter(
    (item) =>
      item.name.toLowerCase().includes(name.toLowerCase()) ||
      item.pinyin.toLowerCase().includes(name.toLowerCase())
  );
};

/**
 * 按照拼音首字母大写分组
 * [{type:'A',[]}, {type:'B',[]}]
 * @param {*} cityList
 * @returns
 */
const cityGroupConvert = (cityList = []) => {
  return cityList.reduce((groups, city) => {
    const { pinyin } = city;
    let type = pinyin.substr(0, 1).toUpperCase();

    let groupArr = groups.filter((item) => item.type === type) || [];
    if (groupArr.length === 0) {
      groups.push({ type, items: [city] });
    } else {
      groupArr[0].items.push(city);
    }
    return groups;
  }, []);
};

const useCityList = (props) => {
  const { name, list, getCityList } = props;

  useEffect(() => {
    list.length === 0 && getCityList();
    return () => {};
  }, [list.length, getCityList]);

  const cityGroups = useMemo(() => {
    return cityGroupConvert(citySearch(citySort(list), name));
  }, [list, name]);

  return {
    cityGroups,
  };
};

const useHandeleClick = (props) => {
  const navigate = useNavigate();

  let { changeCity, clearCinemaList } = props;
  const handleClick = useCallback(
    (city) => {
      let { cityId: id, name } = city;

      // 切换城市
      changeCity({ id, name });
      // 清空影院缓存
      clearCinemaList();
      navigate('/cinema');
    },
    [navigate, changeCity, clearCinemaList]
  );

  return { handleClick };
};

const CityContent = (props) => {
  const { cityGroups } = useCityList(props);
  const { handleClick } = useHandeleClick(props);

  return (
    <IndexBar>
      {cityGroups.map((group) => {
        const { type, items } = group;
        return (
          <IndexBar.Panel
            index={type}
            title={`${type}`}
            key={`${type}`}>
            <List>
              {items.map((item) => (
                <List.Item
                  clickable={false}
                  key={item.cityId}
                  onClick={() => handleClick(item)}>
                  {item.name}
                </List.Item>
              ))}
            </List>
          </IndexBar.Panel>
        );
      })}
    </IndexBar>
  );
};

const City = (props) => {
  const [name, setName] = useState('');

  useAutoHandleTabbar();

  const navigate = useNavigate();
  const onBack = useCallback(() => {
    navigate('/cinema');
  }, [navigate]);
  return (
    <div>
      <div className={style.header}>
        <NavBar
          style={{ '--height': '50px' }}
          backArrow={<CloseOutline />}
          onBack={onBack}>
          标题
        </NavBar>
      </div>
      <div className={style.search}>
        <SearchBar
          style={{ '--background': '#ffffff', margin: '10px' }}
          placeholder="请输入城市名或者拼音"
          showCancelButton
          value={name}
          onChange={(val) => setName(val)}
        />
      </div>
      <div className={style.content}>
        <CityContent
          name={name}
          {...props}
        />
      </div>
    </div>
  );
};

const MapStateToPropsParam = (state) => {
  return {
    list: state.CityReducer.cityList,
  };
};

const MapDispatchToPropsParam = {
  getCityList,
  changeCity,
  clearCinemaList,
};

export default connect(MapStateToPropsParam, MapDispatchToPropsParam)(City);
